import { observable, action, runInAction } from 'mobx';
import { $toast, $src } from '@/cross/utils';
import MimSdk from '../../utils/sdk';
// import { showNotification } from '../../utils/nim/NIM_Android_Push';
import util from '../../utils/im';
import formatLastMsgText from '../../utils/formatLastMsgText';
import navigation from '@/cross/route/navigation';
import Taro from '@tarojs/taro';
// import Realm from 'realm'

import imAction from './msg';
import { imServer, Runtime } from '@/config';
import { IMessage, ISession, IUser } from '../../types';
import { ISysMsgUnRead, ISystemMessage } from '../../types/model/SystemMessage';
import { IBlackItem, IMuteItem } from '../../types/model/Device';
import uuid from '../../utils/uuid';
import { ChatPageProps } from '../pages/Chat';

import { $getDeviceInfo, $getDevicePushId, afterOpenInApp } from '@/cross/utils/device';

export const IM: {
  mim: MimSdk | null;
  sound: null;
} = {
  mim: null,
  // 全局只有一个声音
  sound: null,
};

interface IUsersMap {
  [propName: string]: IUser;
}

class store {
  /** 当前用户账号 */
  account = '';
  client = '';
  @observable user?: IUser;

  /* 当前会话ID */
  @observable currentSessionId = '';
  @observable currentSession?: ISession;
  @observable sessionlist: ISession[] = [];
  @observable messages = {};
  @observable msgCount = 0;
  @observable unreadCount = 0;

  @observable friendslist = [];
  @observable friendFlags = new Map();
  @observable usersMap: IUsersMap = {};

  @observable currentSessionMsgs: IMessage[] = [];
  // 黑名单静音列表
  @observable blacklist: IBlackItem[] = [];
  @observable mutelist: IMuteItem[] = [];
  // 数据
  @observable unReadSysMsgCount: ISysMsgUnRead = {
    total: 0, // 总共的未读数
    friend: 0, // 所有跟好友相关的系统通知的未读数
    addFriend: 0, // 直接加为好友的未读数
    applyFriend: 0, // 申请加为好友的未读数
    passFriendApply: 0, // 通过好友申请的未读数
    rejectFriendApply: 0, // 拒绝好友申请的未读数
    deleteFriend: 0, // 删除好友的未读数
    team: 0, // 所有跟群相关的系统通知的未读数
    teamInvite: 0, // 入群邀请的未读数
    rejectTeamInvite: 0, // 接受入群邀请的未读数
    applyTeam: 0, // 入群申请的未读数
    rejectTeamApply: 0, // 拒绝入群申请的未读数
  };
  // 系统消息 如加好友
  @observable sysmsgs: ISystemMessage[] = [];
  // 连接状态
  @observable connect_state = 'connecting';
  @observable connect_state_text = '连接中...';

  // mutations
  @action CHANGE_CONNECT_STATE(state: string) {
    console.log('CHANGE_CONNECT_STATE', state);
    this.connect_state = state;
    switch (state) {
      case 'connecting':
        this.connect_state_text = '连接中...';
        break;
      case 'connect':
        this.connect_state_text = '连接成功';
        setTimeout(() => {
          this.connect_state_text = '';
        }, 1500);
        break;
      case 'disconnect':
        this.connect_state_text = '未连接';
        break;
      case 'connect_error':
        this.connect_state_text = '请检查手机网络';
        break;
      case 'connect_timeout':
        this.connect_state_text = '连接超时';
        break;
      case 'reconnect':
        this.connect_state_text = '连接成功';
        setTimeout(() => {
          this.connect_state_text = '';
        }, 1500);
        break;
      case 'reconnecting':
        this.connect_state_text = '连接中...';
        break;
      case 'reconnect_error':
        this.connect_state_text = '请检查手机网络';
        break;
      case 'reconnect_failed':
        this.connect_state_text = '请检查手机网络';
        break;
      default:
        break;
    }
  }

  connect({ account, token, client }: { account: string; token: string; client: string }) {
    console.log('开始连接');
    // $toast('开始连接')
    // NimSdk.usePlugin({
    // 	db: Realm,
    // });
    this.account = account;
    this.client = client;
    IM.mim = new MimSdk({
      debug: false,
      server: imServer,
      account,
      token,
      client,
      deviceId: uuid(),
      type: 'app',
      os: $getDeviceInfo().os === 'ios' ? 'ios' : 'android',
      db: true,
      fetchPushId: () => {
        return $getDevicePushId();
      },
      // 目前仅用于更新本人信息
      onuser: (user) => {
        this.user = user;
      },
      onusers: (usersMap) => {
        console.log('[usersMap] ', usersMap);
        this.usersMap = usersMap;
      },
      onsessions: this.onSession,
      onupdatesession: (session) => this.onSession([session]),
      ondeletesession: (scene, to) => this.onDeleteSession(scene, to),
      // syncMsgReceipts: true, // 是否同步已读回执时间戳, 默认true. 如果传false就收不到已读回执时间戳.
      // 同步未读数
      syncSessionUnread: true,
      onsysmsgunread: (unReadSysMsgCount) => {
        runInAction(() => {
          this.unReadSysMsgCount = unReadSysMsgCount;
        });
      },
      // 同步消息
      onmsg: (msg) => {
        console.log('====================================');
        console.log('[onmsg]', msg, this.currentSessionId, ' === ', msg.sessionId);
        console.log('====================================');
        if (this.currentSessionId === msg.sessionId) {
          // 判断是否本机发送的消息
          if (
            msg.from !== this.account ||
            this.currentSessionMsgs.filter((msg) => msg.type !== 'timeTag')[0].idClient !==
              msg.idClient
          ) {
            runInAction(() => {
              imAction.appendSessionMsg(msg);
            });
            IM.mim?.sendMsgReceipt({
              msg,
              done: function sendMsgReceiptDone(error) {
                // do something
                console.log('[sendMsgReceiptDone Error]', error);
              },
            });
          }
        } else {
          // 透传通知
          // $toast('收到通知')
          let showText = '';
          // if (msg.type === 'text') {
          // 	showText = msg.text;
          // } else {
          // 	showText = util.mapMsgType(msg);
          // }
          // if (Platform.OS === 'android') {
          // 	showNotification({
          // 		icon: '', title: msg.fromNick, content: showText, time: `${msg.time}`,
          // 	});
          // } else {
          // 	PushNotificationIOS.presentLocalNotification({
          // 		alertBody: msg.fromNick + ': ' + showText,
          // 		alertAction: "查看",
          // 		category: "push",
          // 		userInfo: {
          // 			action: 'IM_MESSAGE',
          // 			scene: msg.scene,
          // 			to: msg.from
          // 		}
          // 	})
          // }
        }
      },
      onconnect: () => {
        // $toast('IM连接成功')
        console.log('IM连接成功');
        // 获取本地通知信息
        IM.mim?.getLocalSysMsgs({
          category: 'friend',
          // type: '',
          read: false,
          // lastIdServer: '',
          limit: 100,
          done: (err, res) => {
            if (err) return;
            console.log('====================================');
            console.log('[系统通知 getLocalSysMsgs]', res);
            console.log('====================================');
            this.insertOrUpdateSysMsg(res.sysMsgs);
          },
        });
      },
      // 系统通知
      onofflinesysmsgs: async (res) => {
        console.log('====================================');
        console.log('[系统通知 onofflinesysmsgs]', res);
        console.log('====================================');
        this.insertOrUpdateSysMsg(res);
        // alert('onofflinesysmsgs-' + JSON.stringify(res))
      },
      onsysmsg: (res) => {
        console.log('====================================');
        console.log('[系统通知 onsysmsg]', res);
        console.log('====================================');
        // alert('onsysmsg-' + JSON.stringify(res))
        this.insertOrUpdateSysMsg([res], true);
        //
        // if (Platform.OS === 'android') {
        // 	if (res.type === 'applyFriend') {
        // 		// return console.log({
        // 		// 	icon: '', title: '系统消息', content: '新的好友请求', time: $moment().format('HH:mm'),
        // 		// })
        // 		showNotification({
        // 			icon: '', title: '新消息', content: '新的好友请求', time: `${ Date.now() }`,
        // 		});
        // 	}
        // 	if (res.type === 'passFriendApply') {
        // 		// return console.log({
        // 		// 	icon: '', title: '系统消息', content: '对方通过您的好友请求', time: $moment().format('HH:mm'),
        // 		// })
        // 		showNotification({
        // 			icon: '', title: '新消息', content: '对方通过您的好友请求', time: `${ Date.now() }`,
        // 		});
        // 	}
        // } else {
        // 	if (res.type === 'applyFriend') {
        // 		PushNotificationIOS.presentLocalNotification({
        // 			alertBody: '新的好友请求',
        // 			alertAction: "查看",
        // 			category: "push",
        // 			userInfo: {
        // 				action: 'applyFriend'
        // 			}
        // 		})
        // 	}
        // 	if (res.type === 'passFriendApply') {
        // 		PushNotificationIOS.presentLocalNotification({
        // 			alertBody: '对方通过您的好友请求',
        // 			alertAction: "查看",
        // 			category: "push",
        // 			userInfo: {
        // 				action: 'passFriendApply'
        // 			}
        // 		})
        // 	}
        // }
      },
      onofflinecustomsysmsgs: (res) => {
        console.log('====================================');
        console.log('[离线自定义系统通知 onofflinecustomsysmsgs]', res);
        console.log('====================================');
        // alert('onofflinecustomsysmsgs-' + JSON.stringify(res))
        // $toast('收到离线自定义通知')
      },
      oncustomsysmsg: (res) => {
        console.log('====================================');
        console.log('[自定义系统通知 oncustomsysmsg]', res);
        console.log('====================================');
        // alert('oncustomsysmsg-' + JSON.stringify(res))
        // const noticeMsg = {
        // 	type: 'NEW_ORDER', // NEW_ORDER 有新的单可以抢
        // 	value: {} // 值可以是 json object，或者 string， 或者 number
        // }

        // $toast('收到自定义通知')
        if ($getDeviceInfo().os === 'android') {
          // showNotification({
          // 	icon: '', title: '新消息', content: res.apnsText, time: `${ Date.now() }`,
          // });
        } else {
          // if (res.apnsText) {
          // 	let userInfo = {}
          // 	try {
          // 		userInfo = res.content ? JSON.parse(res.content) : {}
          // 	} catch (e) {}
          // 	PushNotificationIOS.presentLocalNotification({
          // 		alertBody: res.apnsText,
          // 		alertAction: "查看",
          // 		category: "push",
          // 		userInfo
          // 	})
          // }
          // .then(res => {
          // 	alert(321)
          // }).catch(e => {
          // 	alert(123)
          // })
        }
      },
      onwillreconnect: () => {},
      ondisconnect: () => {
        // $toast('IM已断开')
      },
      onerror: (event, obj) => {
        console.log('IM error:', event, obj);
      },
      onconnectchange: (state) => {},
      onloginportschange: (loginPorts) => {},
      // 黑名单静音列表
      syncRelations: true,
      onblacklist: (blacklist) => {
        this.blacklist = blacklist;
      },
      onmutelist: (mutelist) => {
        this.mutelist = mutelist;
      },
    });
    // 清除ios角标
    if ($getDeviceInfo().os === 'ios') {
      try {
        // PushNotificationIOS.setApplicationIconBadgeNumber(0);
      } catch (e) {}
    }
  }

  /**
   * 检查是不是好友
   */
  checkIsFriend(accid: string) {
    let isFriend = this.friendFlags.get(accid);
    return isFriend;
  }

  /**
   * 接收系统消息
   * @param {Array} msgs 消息数组
   * @param {Boolean} isAppend 是否是单个消息
   */
  @action insertOrUpdateSysMsg(msgs: ISystemMessage[], isAppend?: boolean) {
    console.log('====================================');
    console.log('[insertOrUpdateSysMsg]', msgs);
    console.log('====================================');
    // 对输入进行追加或替换更新
    let sysmsgs: ISystemMessage[] = ([] as ISystemMessage[]).concat(this.sysmsgs.slice());
    // 去重
    msgs.forEach((msg) => {
      // 目前只处理申请好友通知
      if (msg.type === 'applyFriend') {
        let index = sysmsgs.findIndex((item) => item.from === msg.from);
        if (index > -1) {
          sysmsgs[index] = msg;
        } else {
          sysmsgs.push(msg);
        }
      }
      // 如果有通过好友请求则刷新
      if (msg.type === 'passFriendApply' && isAppend) {
        // this.fetchFriendList()
      }
      // 好友被删除
      if (msg.type === 'deleteFriend') {
        // this.fetchFriendList()
      }
    });
    console.log('====================================');
    console.log(sysmsgs);
    console.log('====================================');
    // 获取联系人信息后保存
    // appStore.auth.fetchUserInfo({
    // accids: sysmsgs.map(item => item.from)
    // }).then(() => {
    runInAction(() => {
      this.sysmsgs = sysmsgs;
    });
    // }).catch(e => {})
  }
  @action logout = () => {
    return new Promise<void>((resolve, reject) => {
      // 清空数据
      this.usersMap = {};
      this.friendslist = [];
      this.friendFlags = new Map();
      this.sysmsgs = [];
      this.sessionlist = [];
      this.unreadCount = 0;
      this.currentSessionMsgs = [];
      this.currentSessionId = '';

      if (IM.mim) {
        IM.mim.logout({
          done(error) {
            if (error) {
              console.log(error);
              return reject();
            }
            resolve();
            // $toast('已断开连接')
            IM.mim = null;
          },
        });
      } else {
        resolve();
      }
    });
  };
  @action onSession = (sessions: ISession[]) => {
    const { account } = this;
    const usersMap = this.usersMap;
    let unreadCount = 0;
    this.sessionlist =
      IM.mim
        ?.mergeSessions(this.sessionlist, sessions)
        .map((session) => {
          session.name = '';
          session.avatar = '';
          if (session.to) {
            if (!usersMap[session.to]) {
              console.warn('用户信息未拉取: onSession');
              return session;
            }
            session.name = util.getFriendAlias(usersMap[session.to]);
            session.avatar = usersMap[session.to].avatar;
          }
          if (!session.lastMsg) {
            return session;
          }
          const lastMsg = session.lastMsg || {};
          session.lastMsgShow = formatLastMsgText(lastMsg);
          if (session.lastMsg.time) {
            session.updateTimeShow = util.formatDate(session.lastMsg.time, true);
          }
          // 如果当前正在会话则强制清空未读
          if (this.currentSessionId === session.sessionId) {
            console.log('[current session] ', session);
            if (session.unread && session.unread > 0) {
              session.unread = 0;
              IM.mim?.clearSessionUnread(session.sessionId);
            }
          }
          unreadCount += session.unread || 0;
          return session;
        })
        .sort((a, b) => {
          const time1 = a.lastMsg ? a.lastMsg.time || 0 : a.updateTime || 0;
          const time2 = b.lastMsg ? b.lastMsg.time || 0 : b.updateTime || 0;
          return time2 - time1;
        }) || [];
    this.unreadCount = unreadCount;
    console.log('====================================');
    console.log('this.sessionList', this.sessionlist);
    console.log('====================================');
  };
  @action onDeleteSession = (scene: string, to: string) => {
    let i = this.sessionlist.findIndex((item) => item.scene === scene && item.to === to);
    if (i > -1) {
      this.sessionlist.splice(i, 1);
    }
  };

  /**
   * 重新修改云信会员信息
   */
  updateImUserInfo(data: { nick?: string; avatar?: string }) {
    return new Promise((resolve, reject) => {
      IM.mim?.updateMyInfo({
        ...data,
        done(error, user) {
          console.log('====================================');
          console.log('updateImUserInfo', user);
          console.log('====================================');
          if (error) return reject(error);
          resolve(user);
        },
      });
    });
  }

  /**
   * 会话相关
   */
  startChat = ({ to, scene = 'p2p' }: { to: string; scene: 'p2p' | 'team' }) => {
    if (Runtime !== 'native') {
      return afterOpenInApp('Sessions', {}, () => {});
    }
    let sessionId = scene + '-' + to;
    if (to === this.account) return $toast('不可以跟自己聊天');
    imAction.getLocalMsgs(sessionId, { reset: true });
    IM.mim?.fetchUser([to]).then(({ usersMap }) => {
      let user = usersMap[to];
      this.setCurrentSession(sessionId);
      navigation.navigate<ChatPageProps>('Chat', {
        params: {
          session: {
            sessionId,
            to,
            name: user.nick,
            avatar: user.avatar,
            scene,
          },
        },
      });
    });
  };

  @action setCurrentSession = (sessionId: string) => {
    IM.mim?.setCurrSession(sessionId);
    this.currentSessionId = sessionId;
    this.currentSession = this.sessionlist.find((item) => (item.sessionId = sessionId));
  };

  @action resetCurrSession = () => {
    this.currentSessionMsgs = [];
    IM.mim?.resetCurrSession();
    this.currentSessionId = '';
  };

  @action deleteLocalSession = (sessionId: string, account: string) => {
    IM.mim?.deleteSession({
      scene: 'p2p',
      to: account,
      done: (error, obj) => {
        console.log('[deleteSession error] ', error, obj);
        IM.mim?.deleteLocalSession({
          id: sessionId,
          done: (error) => {
            console.log('[] ');
            if (error) {
              // $toast('删除会话失败')
              return;
            }
            this.sessionlist = IM.mim?.cutSessionsByIds(this.sessionlist, [sessionId]) || [];
          },
        });
      },
    });
  };

  /**
   * 黑名单
   */
  getRelations = () => {
    IM.mim?.getRelations({
      done: (err, res) => {
        console.log('[getRelations] ', res);
        if (!err) {
          this.blacklist = res.blacklist;
          this.mutelist = res.mutelist;
        }
      },
    });
  };

  markInMutelist = (account: string, isAdd: boolean) => {
    return new Promise((resolve, reject) => {
      IM.mim?.markInMutelist({
        account,
        isAdd,
        done: (err, obj) => {
          console.log('[markInMutelist] ', err, obj);
          if (err) return reject(err);
          resolve(obj);
          // 刷新
          this.getRelations();
        },
      });
    });
  };

  markInBlacklist = (account: string, isAdd: boolean) => {
    return new Promise((resolve, reject) => {
      IM.mim?.markInBlacklist({
        account,
        isAdd,
        done: (err, obj) => {
          console.log('[markInBlacklist] ', err, obj);
          if (err) return reject(err);
          resolve(obj);
          // 刷新
          this.getRelations();
        },
      });
    });
  };

  /**
   * 好友相关
   */
  onFriendsChange = async (friends: object[], isReset: boolean) => {
    // console.log('====================================');
    // console.log('onfriends:', friends);
    // console.log('====================================');
    // if (isReset) {
    // 	this.friendFlags = new Map()
    // }
    // let accids = []
    // friends.forEach((item) => {
    // 	accids.push(item.account)
    // 	// set(nimStore.friendFlags, item.account, true);
    // 	this.friendFlags.set(item.account, true);
    // 	const tempAccount = item.account;
    // 	if (tempAccount) {
    // 		const userInfo = this.usersMap[tempAccount];
    // 		if (userInfo) {
    // 			this.usersMap[tempAccount] = Object.assign(userInfo, item);
    // 		} else {
    // 			this.usersMap[tempAccount] = item;
    // 		}
    // 	}
    // });
    // friends = friends.map((item) => {
    // 	if (typeof item.isFriend !== 'boolean') {
    // 		item.isFriend = true;
    // 	}
    // 	return item;
    // });
    // // 批量根据yunxinId 获取用户信息
    // // await appStore.auth.fetchUserInfo({
    // // 	accids
    // // })
    // this.friendslist = IM.mim.mergeFriends(this.friendslist, friends);
    // this.friendslist = IM.mim.cutFriends(this.friendslist, friends.invalid);
  };

  fetchFriendList() {
    return new Promise((resolve, reject) => {
      // IM.mim.getFriends({
      // 	done: (error, friends) => {
      // 		if (!error) {
      // 			this.onFriendsChange(friends, true)
      // 			resolve()
      // 		} else {
      // 			reject()
      // 		}
      // 	}
      // });
    });
  }

  applyFriend(account: string) {
    return new Promise<void>((resolve, reject) => {
      // IM.mim?.applyFriend({
      // 	account,
      // 	ps: '',
      // 	done: (error) => {
      // 		console.log('====================================');
      // 		console.log(error);
      // 		console.log('====================================');
      // 		if (error) {
      // 			return reject(error)
      // 		}
      // 		resolve()
      // 	},
      // });
    });
  }

  /**
   * 通过好友请求
   */
  // passFriendApply({
  // 	account,
  // 	idServer
  // }) {
  // 	return new Promise((resolve, reject) => {
  // 		IM.mim.passFriendApply({
  // 			idServer,
  // 			account,
  // 			ps: '',
  // 			done: (error) => {
  // 				if (error) {
  // 					return reject(error)
  // 				}
  // 				resolve()
  // 				// 重新获取好友列表
  // 				this.fetchFriendList()
  // 			},
  // 		});
  // 		// 删除本条通知消息
  // 		this.deleteLocalSysMsg({idServer})
  // 	})
  // }

  /**
   * 删除本地系统通知
   */
  @action deleteLocalSysMsg = ({ id }: { id: string }) => {
    return new Promise<void>((resolve, reject) => {
      IM.mim?.deleteLocalSysMsg({
        id,
        done: (error) => {
          runInAction(() => {
            let i = this.sysmsgs.findIndex((item) => item._id === id);
            this.sysmsgs.splice(i, 1);
          });
          resolve();
        },
      });
    });
  };

  /**
   * 删除好友
   */
  // deleteFriend(yunxinAccid) {
  // 	return new Promise((resolve, reject) => {
  // 		IM.mim.deleteFriend({
  // 			account: yunxinAccid,
  // 			done: (error) => {
  // 				if (error) {
  // 					return reject(error)
  // 				}
  // 				resolve()
  // 				// 重新获取好友列表
  // 				this.fetchFriendList()
  // 			},
  // 		});
  // 	})
  // }

  // updateFriend({
  // 	account,
  // 	alias,
  // 	custom
  // }) {
  // 	return new Promise((resolve, reject) => {
  // 		IM.mim.updateFriend({
  // 			account,
  // 			alias,
  // 			custom,
  // 			done: (e, res) => {
  // 				if (e) return reject(e)
  // 				resolve()
  // 				// 重新获取好友列表
  // 				this.fetchFriendList().then(res => {
  // 					// 使会话列表更新
  // 					this.sessionlist = this.sessionlist.slice()
  // 				}).catch(e => {})
  // 			}
  // 		});
  // 	})
  // }

  /** 语音播放 */
  @observable currentPlayingAudioMsgId = '';
  @observable currentPlayingAudioState: 'loading' | 'playing' | 'stop' = 'stop';
  innerAudioContext: any = null;
  @action onStop = () => {
    this.currentPlayingAudioMsgId = '';
    this.currentPlayingAudioState = 'stop';
    this.innerAudioContext = null;
  };
  @action playAudioMsg = async (msg: IMessage) => {
    if (msg.type === 'audio' && msg.file) {
      if (this.currentPlayingAudioMsgId === msg.idServer) {
        if (this.currentPlayingAudioState === 'playing') {
          this.innerAudioContext.pause();
        } else {
          this.innerAudioContext.play();
        }
      } else {
        if (this.currentPlayingAudioState === 'playing') {
          await this.innerAudioContext.pause();
        }
        const soundUrl = $src(msg.file.url + '?attname=' + msg.file.url + '.aac', {
          source: true,
        });
        this.innerAudioContext = Taro.createInnerAudioContext();
        this.innerAudioContext.onPlay(() => {
          this.currentPlayingAudioMsgId = msg.idServer || '';
          this.currentPlayingAudioState = 'playing';
        });
        this.innerAudioContext.onError((e: any) => {
          // 重试
          setTimeout(() => {
            this.innerAudioContext.play();
          }, 500);
        });
        this.innerAudioContext.onPause(this.onStop);
        this.innerAudioContext.onEnded(this.onStop);
        this.innerAudioContext.src = soundUrl;
        this.innerAudioContext.play();
      }
    }
  };
}

export default new store();
